#!/bin/bash
#
# mysqld	This shell script takes care of starting and stopping
#		the MySQL subsystem (mysqld).
#
# chkconfig: - 64 36
# description:	MySQL database server.
# processname: mysqld
# config: /etc/my.cnf
# pidfile: /var/run/mysqld/mysqld.pid
### BEGIN INIT INFO
# Provides: mysqld
# Required-Start: $local_fs $remote_fs $network $named $syslog $time
# Required-Stop: $local_fs $remote_fs $network $named $syslog $time
# Short-Description: start and stop MySQL server
# Description: MySQL database server
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network
# Set timeouts here so they can be overridden from /etc/sysconfig/mysqld
STARTTIMEOUT=120
STOPTIMEOUT=60
prog="mysqld2"
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog

lockfile=/var/lock/subsys/$prog

# extract value of a MySQL option from config files
# Usage: get_mysql_option SECTION VARNAME DEFAULT
# result is returned in $result
# We use my_print_defaults which prints all options from multiple files,
# with the more specific ones later; hence take the last match.
get_mysql_option(){
	result=`${eprefix}/bin/my_print_defaults -c ${myconfig}/my.cnf "$1" | sed -n "s/^--$2=//p" | tail -n 1`
	#配置项没有指定或者配置项所指定的位置已经有文件存在就用第三个参数指定
	if [ -z "$result" -o -e "$result" ]; then
	    # not found, use default
	    result="$3"
	fi
}

start(){
    [ -x $exec ] || exit 5
    # check to see if it's already running
    MYSQLDRUNNING=0
    if [ -f "$mypidfile" ]; then
	MYSQLPID=`cat "$mypidfile" 2>/dev/null`
	if [ -n "$MYSQLPID" ] && [ -d "/proc/$MYSQLPID" ] ; then
	    MYSQLDRUNNING=1
	fi
    fi
    RESPONSE=`${eprefix}/bin/mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1`
    if [ $MYSQLDRUNNING = 1 ] && [ $? = 0 ]; then
	# already running, do nothing
	action $"Starting $prog: " /bin/true
	ret=0
    elif [ $MYSQLDRUNNING = 1 ] && echo "$RESPONSE" | grep -q "Access denied for user"
    then
	# already running, do nothing
	action $"Starting $prog: " /bin/true
	ret=0
    else
    	# prepare for start
	touch "$errlogfile" 2>/dev/null
	if [ $? -ne 0 ]; then
	     # failed to touch log file, probably insufficient permissions
	    action $"Starting $prog: " /bin/false
	    return 4
	fi
	chown mysql:mysql "$errlogfile" 
	chmod 0640 "$errlogfile"
	[ -x /sbin/restorecon ] && /sbin/restorecon "$errlogfile"
	if [ ! -d "$datadir/mysql" ] ; then
	    # First, make sure $datadir is there with correct permissions
	    if [ ! -e "$datadir" -a ! -h "$datadir" ]
	    then
		mkdir -p "$datadir" || exit 1
	    fi
	    chown mysql:mysql "$datadir"
	    chmod 0755 "$datadir"
	    [ -x /sbin/restorecon ] && /sbin/restorecon "$datadir"
	    # Now create the database
	    action $"Initializing MySQL database: " ${eprefix}/bin/mysql_install_db --datadir="$datadir" --user=mysql
	    ret=$?
	    chown -R mysql:mysql "$datadir"
	    if [ $ret -ne 0 ] ; then
		return $ret
	    fi
	fi
	chown mysql:mysql "$datadir"
	chmod 0755 "$datadir"
	# We check if there is already a process using the socket file,
	# since otherwise this init script could report false positive
	# result and mysqld_safe would remove the socket file, which
	# actually uses a different daemon.
	if fuser "$socketfile" &>/dev/null ; then
	    echo "Socket file $socketfile exists. Is another MySQL daemon already running with the same unix socket?"
	    action $"Starting $prog: " /bin/false
	    return 1
	fi
	# Pass all the options determined above, to ensure consistent behavior.
	# In many cases mysqld_safe would arrive at the same conclusions anyway
	# but we need to be sure.  (An exception is that we don't force the
	# log-error setting, since this script doesn't really depend on that,
	# and some users might prefer to configure logging to syslog.)
	# Note: set --basedir to prevent probes that might trigger SELinux
	# alarms, per bug #547485
	#启动前检查端口是否被占用 为什么要启动前检查 因为这个服务可能已经启动了 所以要先检查pidfile
	get_mysql_option mysqld port "3306"
	myport="$result"
	if [ `netstat -anp | grep ':'$myport | wc -l` -gt 0 ];then
		echo '该端口已被占用,请修改my.cnf配置文件更换' && exit
	fi
	$exec   --datadir="$datadir" --socket="$socketfile" \
		--pid-file="$mypidfile" \
		--basedir="$prefix" --user=mysql >/dev/null 2>&1 &
	safe_pid=$!
	# Spin for a maximum of N seconds waiting for the server to come up;
	# exit the loop immediately if mysqld_safe process disappears.
	# Rather than assuming we know a valid username, accept an "access
	# denied" response as meaning the server is functioning.
	ret=0
	TIMEOUT="$STARTTIMEOUT"
	while [ $TIMEOUT -gt 0 ]; do
	    RESPONSE=`${eprefix}/bin/mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1`
	    mret=$?
	    if [ $mret -eq 0 ]; then
		break
	    fi
	    # exit codes 1, 11 (EXIT_CANNOT_CONNECT_TO_SERVICE) are expected,
	    # anything else suggests a configuration error
	    if [ $mret -ne 1 -a $mret -ne 11 ]; then
		echo "$RESPONSE"
		echo "Cannot check for MySQL Daemon startup because of mysqladmin failure."
		ret=1
		break
	    fi
	    echo "$RESPONSE" | grep -q "Access denied for user" && break
	    if ! /bin/kill -0 $safe_pid 2>/dev/null; then
		echo "MySQL Daemon failed to start."
		ret=1
		break
	    fi
	    sleep 1
	    let TIMEOUT=${TIMEOUT}-1
	done
	if [ $TIMEOUT -eq 0 ]; then
	    echo "Timeout error occurred trying to start MySQL Daemon."
	    ret=1
	fi
	if [ $ret -eq 0 ]; then
	    action $"Starting $prog: " /bin/true
	    chmod o+r $mypidfile >/dev/null 2>&1
	    touch $lockfile
	else
	    action $"Starting $prog: " /bin/false
	fi
    fi
    return $ret
}

stop(){
	if [ ! -f "$mypidfile" ]; then
	    # not running; per LSB standards this is "ok"
	    action $"Stopping $prog: " /bin/true
	    return 0
	fi
	MYSQLPID=`cat "$mypidfile" 2>/dev/null`
	if [ -n "$MYSQLPID" ]; then
	    /bin/kill "$MYSQLPID" >/dev/null 2>&1
	    ret=$?
	    if [ $ret -eq 0 ]; then
		TIMEOUT="$STOPTIMEOUT"
		while [ $TIMEOUT -gt 0 ]; do
		    /bin/kill -0 "$MYSQLPID" >/dev/null 2>&1 || break
		    sleep 1
		    let TIMEOUT=${TIMEOUT}-1
		done
		if [ $TIMEOUT -eq 0 ]; then
		    echo "Timeout error occurred trying to stop MySQL Daemon."
		    ret=1
		    action $"Stopping $prog: " /bin/false
		else
		    rm -f $lockfile
		    rm -f "$socketfile"
		    action $"Stopping $prog: " /bin/true
		fi
	    else
		action $"Stopping $prog: " /bin/false
	    fi
	else
	    # failed to read pidfile, probably insufficient permissions
	    action $"Stopping $prog: " /bin/false
	    ret=4
	fi
	return $ret
}
 
restart(){
    stop
    start
}

condrestart(){
    [ -e $lockfile ] && restart || :
}

#检查本机上mysql的rpm安装情况
checkrpm(){
  if [ `rpm -q mysql-server | wc -l` -eq 0 ];then
 	echo '本机还未使用rpm安装mysqld服务端'
	return 0
  else
	return 1
  fi

  if [ `rpm -q mysql | wc -l` -eq 0 ];then
 	echo '本机还未使用rpm安装mysql客户端'
  fi
}
#检查配置文件和参数分析
#stop start status各函数的第一个参数 $1
#0表示rpm自带的mysq -l表示全部选择
#1表示第一个编译的mysql 2表示第二个 以此类推
checkcnf(){
	if [ ! -f ~/multi-mysql.cnf ]; then
		echo '主工作目录下没有配置文件multi-mysql.cnf 请到'`echo ~`'下主动创建'`echo ~`'/multi-mysql.cnf'
		exit
	fi
	[ -z $2 ] && echo $'Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload} number' && exit
	[ $2 -lt 0 -a $2 -ne -1 ] && echo '第二个参数必须为-1 0 或者任何正整数' && exit
	#检查配置文件的行数来确定源码编译mysql数目(去掉空白行)
	compileCount=`cat ~/multi-mysql.cnf | sed '/^$/d' | wc -l`
	checkrpm
	rpm=$?
	#总mysql数目
	if [ $rpm ];then
		totalCount=$(($compileCount+1))
	else
		totalCount=$compileCount
	fi
	[ $totalCount -eq 0 ] && echo '本机没有安装mysql' && exit 1
	if [ $2 -eq 0 ];then
		if [ $rpm ];then
			service mysqld start
			exit
		else
			echo '本机上没有安装rpm的mysql' && exit 1
		fi
	fi
	[ $2 -gt $compileCount ] && echo '参数序列指定的mysql不存在，请检查配置文件' && exit 1
	if [ $2 -eq -1 ];then
		if [ $rpm ];then
			service mysqld start
		fi
		if [ $compileCount -gt 0 ];then
			parsecnf $*
		fi	
	else
		parsecnf $*
	fi
}
#分析配置文件及运行配置文件所列出的mysql序列
parsecnf(){		
	configPath=`echo ~`
      if [ "$1" = "start" ];then
        if [ $2 -eq -1 ];then
	 num=0
	 for line in `cat ${configPath}/multi-mysql.cnf`
	    do
		#记录行数
		num=$(($num+1))
		
		arr=(`echo $line | awk -F: '{print $1,$2,$3}'`)
		prefix=${arr[0]}
		eprefix=${arr[1]}
		myconfig=${arr[2]}
		[ -z $eprefix ] && eprefix=$prefix
		exec="${eprefix}/bin/mysqld_safe"
	
		get_mysql_option mysqld datadir "${prefix}/var"
		datadir="$result"
		get_mysql_option mysqld socket "$datadir/mysql.sock"
		socketfile="$result"
		get_mysql_option mysqld_safe log-error "/var/log/mysqld${2}.log"
		errlogfile="$result"
		get_mysql_option mysqld_safe pid-file "${prefix}/mysqld.pid"
		mypidfile="$result"
		start
		#启动完毕要把pidfile写进multi-mysql.cnf配置文件 在当前行后面添加一项pidfile
		#if [ $? -eq 0 ];then
		#	#sed 变量替换有/的话 就用|来代替原来的sed分割符/
		#	sed -i -e "${num}s|$|&:${mypidfile}|" ${configPath}/multi-mysql.cnf
		#fi
	 done
	else
		prefix=`cat ${configPath}/multi-mysql.cnf | sed -n "${2}p" | awk -F: '{print $1}'`
		eprefix=`cat ${configPath}/multi-mysql.cnf | sed -n "${2}p" | awk -F: '{print $2}'`
		myconfig=`cat ${configPath}/multi-mysql.cnf | sed -n "${2}p" | awk -F: '{print $3}'`
		[ -z $eprefix ] && eprefix=$prefix
		exec="${eprefix}/bin/mysqld_safe"
		get_mysql_option mysqld datadir "${prefix}/var"
		datadir="$result"
		get_mysql_option mysqld socket "$datadir/mysql.sock"
		socketfile="$result"
		get_mysql_option mysqld_safe log-error "/var/log/mysqld${2}.log"
		errlogfile="$result"
		get_mysql_option mysqld_safe pid-file "${prefix}/mysqld.pid"
		mypidfile="$result"
		start
	fi
      elif [ $1 = "stop" ];then
	if [ $2 -eq 0 ];then
		service mysqld stop
	elif [ $2 -eq -1 ];then
		service mysqld stop
		configPath=`echo ~`
		for line in `cat ${configPath}/multi-mysql.cnf`
			do
				prefix=`echo $line | awk -F: '{print $1}'`			
				eprefix=`echo $line | awk -F: '{print $2}'`				
				get_mysql_option mysqld_safe pid-file "${prefix}/mysqld.pid"
				mypidfile="$result"
				stop
		done	
        else
		configPath=`echo ~`
		prefix=`sed -n "${2}p" ${configPath}/multi-mysql.cnf | awk -F: '{print $1}'`
		eprefix=`sed -n "${2}p" ${configPath}/multi-mysql.cnf | awk -F: '{print $2}'`	
		get_mysql_option mysqld_safe pid-file "${prefix}/mysqld.pid"
		mypidfile="$result"
		stop
		
	fi
      fi
}

# See how we were called.
case "$1" in

  start)
    checkcnf $*
    ;;
  stop)
    checkcnf $*
    ;;
  status)
    #status -p "$mypidfile" $prog
    ;;
  restart)
    #restart
    ;;
  condrestart|try-restart)
    #condrestart
    ;;
  reload)
    #exit 3
    ;;
  force-reload)
    #restart
    ;;
  *)
    echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload} number"
    exit 2
esac

exit $?
